package main

import (
	"context"
	"flag"
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/example/video_backend/internal/model"
	"github.com/example/video_backend/internal/router"
	"github.com/example/video_backend/pkg/logger"
	"github.com/example/video_backend/pkg/minio"
	"github.com/example/video_backend/pkg/utils"
	"github.com/spf13/viper"
)

// @title 视频播放平台 API
// @version 1.0
// @description 视频播放平台后端API文档
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.email support@example.com
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:8080
// @BasePath /api/v1

// 处理没有封面的视频
func processVideosWithoutCover() {
	ctx := context.Background()
	logger.Info("开始处理没有封面的视频")

	// 查询cover_url为空字符串的视频
	var videos []model.Video
	result := model.DB.Where("cover_url = ?", "").Find(&videos)
	if result.Error != nil {
		logger.Error("查询没有封面的视频失败: " + result.Error.Error())
		return
	}

	logger.Info(fmt.Sprintf("找到 %d 个没有封面的视频", len(videos)))

	// 处理每个视频
	for i, video := range videos {
		logger.Info(fmt.Sprintf("处理视频 %d/%d: %s (ID: %d)", i+1, len(videos), video.Title, video.ID))

		// 从MinIO下载视频文件
		fileHeader, err := downloadVideoFromMinIO(ctx, video.VideoURL)
		if err != nil {
			logger.Error(fmt.Sprintf("下载视频失败 (ID: %d): %s", video.ID, err.Error()))
			continue
		}

		// 提取视频第一帧
		framePath, err := utils.ExtractFileVideoFirstFrame(fileHeader)
		if err != nil {
			logger.Error(fmt.Sprintf("提取视频帧失败 (ID: %d): %s", video.ID, err.Error()))
			continue
		}

		// 上传封面到MinIO
		coverURL, err := minio.UploadImageFile(ctx, framePath, "covers/")
		if err != nil {
			logger.Error(fmt.Sprintf("上传封面失败 (ID: %d): %s", video.ID, err.Error()))
			// 清理临时文件
			os.Remove(framePath)
			continue
		}

		// 清理临时文件
		os.Remove(framePath)

		// 更新数据库中的cover_url
		updateResult := model.DB.Model(&model.Video{}).Where("id = ?", video.ID).Update("cover_url", coverURL)
		if updateResult.Error != nil {
			logger.Error(fmt.Sprintf("更新封面URL失败 (ID: %d): %s", video.ID, updateResult.Error.Error()))
			continue
		}

		logger.Info(fmt.Sprintf("成功更新视频封面 (ID: %d)", video.ID))
	}

	logger.Info("处理完成")
}

// 从MinIO下载视频文件并返回multipart.FileHeader
func downloadVideoFromMinIO(ctx context.Context, videoURL string) (string, error) {
	// 提取对象名称
	objectName := extractObjectName(videoURL)

	// 创建临时目录和文件
	tempDir := os.TempDir()
	timestamp := time.Now().UnixNano()
	ext := filepath.Ext(objectName)
	tempFilePath := filepath.Join(tempDir, fmt.Sprintf("video_temp_%d%s", timestamp, ext))

	// 从MinIO下载文件
	resp, err := http.Get(videoURL)
	if err != nil {
		return "", fmt.Errorf("下载视频文件失败: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("下载视频文件失败: HTTP %d", resp.StatusCode)
	}

	// 创建临时文件
	tempFile, err := os.Create(tempFilePath)
	if err != nil {
		return "", fmt.Errorf("创建临时文件失败: %w", err)
	}
	defer tempFile.Close()

	// 将视频内容写入临时文件
	size, err := io.Copy(tempFile, resp.Body)
	if err != nil {
		// 清理临时文件
		os.Remove(tempFilePath)
		return "", fmt.Errorf("写入临时文件失败: %w", err)
	}

	logger.Info(fmt.Sprintf("成功下载视频文件: %s, 大小: %d 字节", objectName, size))

	return tempFilePath, nil
}

// 从URL中提取对象名称
func extractObjectName(url string) string {
	// 简化处理：从URL中提取对象名称
	parts := strings.Split(url, "/")
	if len(parts) > 0 {
		return parts[len(parts)-1]
	}
	return url
}
func main() {
	//初始化配置
	InitGlobal()
	cover := flag.Int("cover", 0, "Port to run the server on")
	flag.Parse()
	if *cover == 0 {
		// 初始化路由
		r := router.InitRouter()

		// 启动服务器
		serverPort := viper.GetString("server.port")
		if serverPort == "" {
			serverPort = "8081"
		}

		logger.Info("Starting server on port " + serverPort)
		r.Run(":" + serverPort)
	} else {
		// 处理没有封面的视频
		processVideosWithoutCover()
	}

}
